package main

import (
	"even"
	"fmt"
	"os"
	"runtime"
)

//可以省略字段名称   例如 name string -> string
type People struct {
	string
	age        int
	doSometing func()
}

//定义go中更加通用的类型
//define empty interface as a type
type generalType interface{}

//至少满足int 和 string类型
func mult(f generalType) generalType {
	switch f.(type) {
	case int:
		return f.(int) * 2
	case string:
		return f.(string) + f.(string) + f.(string) + f.(string)
	}
	return f
}

//Map函数支持更加通用的类型
func Map(n []generalType, f func(generalType) generalType) []generalType {
	m := make([]generalType, len(n))
	for k, v := range n {
		m[k] = f(v)
	}
	return m
}
func argFunc(arg ...int) {
	for _, n := range arg {
		fmt.Printf("the args is %d\n", n)
	}
}

func (p *People) methodDoSomething() {
	fmt.Println("a man 's mathod do something")
}

func main() {
	//输出当前go版本  ，go 环境变量
	fmt.Printf("go version : %s\n", runtime.Version())
	fmt.Printf("go arch : %s\n", runtime.GOARCH)
	fmt.Printf("go os : %s\n", os.Getenv("GOOS"))
	fmt.Println("GOROOT : " + os.Getenv("GOROOT"))
	fmt.Println("GOPATH : ", os.Getenv("GOPATH"))

	// different between  array and slice about length
	// and capacity
	a := [10]int{0, 1, 2, 3, 4}

	s := a[0:5]

	fmt.Printf("length of array is %d\n", len(a))
	fmt.Printf("length of slice is %d\n", len(s))
	fmt.Printf("capacity of array is %d\n", cap(a))
	fmt.Printf("capacity of slice is %d\n", cap(s))
	//函数多个参数
	argFunc(a[0], a[1], a[2])

	//将函数作为值（函数指针）
	aFunc := func() {
		fmt.Printf("this is a function as a value\n")
	}
	aFunc() //调用函数

	//将函数作为map的一个值
	var mapFunc = map[int]func() int{
		1: func() int { return 10 },
		2: func() int { return 20 },
		3: func() int { return 30 },
		4: func() int { return 40 },
	}
	for k, v := range mapFunc {
		fmt.Printf("func number :%d address :%d call func :%d\n", k, v, v())
	}

	//import a package
	i := 5
	fmt.Printf("Is %v even ? :%v\n", i, even.Even(i))
	fmt.Printf("Is %v odd ?  :%v \n", i, even.Odd(i))

	aPeople := new(People)
	aPeople.string = "Tmacy"
	aPeople.age = 22
	aPeople.doSometing = func() {
		fmt.Println("a man do something")
	}
	fmt.Printf("%v\n", aPeople)
	aPeople.doSometing()
	aPeople.methodDoSomething()

	// 使用通用类型，针对不同类型做不同处理

	intMap := []generalType{1, 2, 3, 4}
	stringMap := []generalType{"hello", "ni hao", "nice to meet you", "see you"}

	intMapf := Map(intMap, mult)
	stringMapf := Map(stringMap, mult)
	fmt.Printf("intMapf : %v\n", intMapf)
	fmt.Printf("stringMapf : %v\n", stringMapf)

}
